﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MethodWorx.CMS.Membership;
using MethodWorx.CMS.UI.Models;
using MethodWorx.CMS.UI.Application.ActionResults;
using MethodWorx.CMS.Services;
using MethodWorx.Core.DomainModel;
using MethodWorx.Core.Validation;
using MethodWorx.CMS.UI.Areas.Administration.Models;
using MethodWorx.CMS.UI.Application;
using MethodWorx.CMS.Plugins;

namespace MethodWorx.CMS.UI.Areas.Administration.Controllers
{
    public class UserController : ApplicationController, IValidationProvider
    {
        private IUserRepository userRepository;
        private UserService userService;
        private IUnitOfWorkFactory unitOfWorkFactory;
        private User currentUser;
        private PluginService pluginService;

        //
        // GET: /User/
        public UserController(IUserRepository userRepository, UserService userService, IUnitOfWorkFactory unitOfWorkFactory, PluginService pluginService)
        {
            this.userRepository = userRepository;
            this.userService = userService;
            this.unitOfWorkFactory = unitOfWorkFactory;
            this.pluginService = pluginService;
        }

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            this.currentUser = this.userService.GetUserById(Guid.Parse(this.User.Identity.Name));
        }
        
        public ActionResult Index(UserType usertype)
        {
           
            UserViewModel userModel = new UserViewModel();

            userModel.CreateUserViewModel(this.userRepository, usertype);
            userModel.Attributes = this.GetSelectedAttributes(usertype);

            return View(userModel);
        }

        public ActionResult Add()
        {

            AddUserModel model = new AddUserModel(this.userRepository);
            return View(model);
        }

        [HttpPost]
        public ActionResult Add(string submit, FormCollection formCollection)
        {
            switch (submit)
            {
                case "save":
                    AddUserModel model = new AddUserModel(this.userRepository);
                    this.TryUpdateModel(model.CreateUserRequest, "CreateUserRequest", formCollection);
                    this.userService.CreateUser(model.CreateUserRequest, this, this.unitOfWorkFactory);

                    if (this.ModelState.IsValid)
                    {
                        return new CloseDialogResult("save");    
                    }
                    else
                    {
                        return View(model);
                    }
                default:
                    return new CloseDialogResult("cancel");
            }
           
        }


        public bool Validate(object instance)
        {
            return this.TryValidateModel(instance);
        }

        public void AddError(string key, string message)
        {
            this.ModelState.AddModelError("CreateUserRequest." + key, message);
        }

        public bool IsValid()
        {
            return this.ModelState.IsValid;
        }

        [HttpGet]
        public ViewResult ConfigureView(UserType type)
        {
            this.ViewData["Attributes"] = this.userService.GetAttributes(type);
            this.ViewData["SelectedAttributes"] = GetSelectedAttributes(type);

            return View();
        }

        private string [] GetSelectedAttributes(UserType type)
        {
            var plugin = this.pluginService.Plugins.All().FirstOrDefault(p => p.Name == "Internal");
            return this.pluginService.GetUserData<string[]>(plugin, this.currentUser, type + "ViewAttributes") ?? new string[] {};
        }

        [HttpPost]
        public ActionResult ConfigureView(UserType type, string submit, string [] attributes)
        {
            this.ViewData["Attributes"] = this.userService.GetAttributes(type);
            this.ViewData["SelectedAttributes"] = attributes ?? new string[] {};

            var plugin = this.pluginService.Plugins.All().FirstOrDefault(p => p.Name == "Internal");

            switch((submit ?? "").ToLower())
            {
                case "cancel":
                    return new CloseDialogResult();
                    break;
                case "save":
                    this.pluginService.SetUserData(plugin, this.currentUser, type + "ViewAttributes",
                                                   this.ViewData["SelectedAttributes"], true);
                    return new CloseDialogResult("save");
                    break;
            }



            return View();
        }
    }


}
